package com.imhuis.pay.wxpay;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.imhuis.pay.service.IPayService;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.util.EntityUtils;
import org.apache.logging.log4j.util.Strings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;

@Service("wxPayService")
public class WxPayServiceImpl implements IPayService {

    Logger log = LoggerFactory.getLogger(WxPayServiceImpl.class);

    @Autowired
    private HttpClient httpClient;

    @Autowired
    private ObjectMapper objectMapper;

    @Override
    public void payV3() {
        HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi");
        httpPost.addHeader("Accept", "application/json");
        httpPost.addHeader("Content-type","application/json; charset=utf-8");

        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectMapper objectMapper = new ObjectMapper();

        ObjectNode rootNode = objectMapper.createObjectNode();
        /**
         * https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_5_1.shtml
         * appid  string[1,32] - 由微信生成的应用ID，全局唯一。请求基础下单接口时请注意APPID的应用属性，例如公众号场景下，需使用应用属性为公众号的APPID
         * mchid string[1,32] - 直连商户的商户号，由微信支付生成并下发
         * description - 商品描述
         * out_trade_no string[6,32] - 商户系统内部订单号，只能是数字、大小写字母_-*且在同一个商户号下唯一
         * time_expire - 订单失效时间，遵循rfc3339标准格式，格式为YYYY-MM-DDTHH:mm:ss+TIMEZONE
         * notify_url - 异步接收微信支付结果通知的回调地址
         */
        rootNode.put("appid", "应用id")
                .put("mchid","商户号")
                .put("description", "商品描述")
                .put("out_trade_no", "商户订单号")
                .put("notify_url", "https://www.weixin.qq.com/wxpay/pay.do");
        rootNode.putObject("amount")
                // 单位分
                .put("total", 100);
        rootNode.putObject("payer")
                .put("openid", "");

        try {
            objectMapper.writeValue(bos, rootNode);
        } catch (IOException e) {
            e.printStackTrace();
        }

        try {
            httpPost.setEntity(new StringEntity(bos.toString("UTF-8"), "UTF-8"));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        HttpResponse response = null;
        try {
            response = httpClient.execute(httpPost);
        } catch (IOException e) {
            e.printStackTrace();
        }

        String bodyAsString = null;
        try {
            bodyAsString = EntityUtils.toString(response.getEntity());
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 返回预支付会话标识（prepay_id）
        log.info("返回数据 {}", bodyAsString);
    }

    @Override
    public String notifyV3(String notify) {
        /**
         * {
         *     "id": "311fe73f-c397-5e5a-9c8f-9fc94afb387b",
         *     "create_time": "2021-09-28T13:50:48+08:00",
         *     "resource_type": "encrypt-resource",
         *     "event_type": "TRANSACTION.SUCCESS",
         *     "summary": "支付成功",
         *     "resource": {
         *         "original_type": "transaction",
         *         "algorithm": "AEAD_AES_256_GCM",
         *         "ciphertext": "Ay25zutpHN+uMAaO6mqOeZvePpU3VR7wfY4GWlbI+bifz58DbR0BSrpI+kAmE/WnMbgwG5rBQKPzjZcfCIPILVGUMWMaPnGI7CzQ2RHuMXUzGugYH4iJZOjYVmxEJDB3J1OAPJoZC5Xu7b8aFrFbY/WqQ+pUWZnfBEkdyQPx7yHU06b8UEtYZjlbyPPP4XGe42DM6nuWiOmVvDxPtAO4XyZKqzW6WteLzHbF/kqa8f5VzkhXsJV25ytfV9/JM7/KW3nLOgz6KWfsK3K4UmlExK5OewSTGiTjM6pApyXuBSBLSMsI6efhQ6RVRcfcWs8lyDIXsc1BxW+Axvv4Y5NGfsSbBoxF1NhJT+8EScFwrMdOcO2prPFtLzNTsxjsPYTd/OGA2c1mgImjsJBMhSe/vkZW0bmXXsU/M/EBpzu72aXHbj/yVhjtJeG9k/RGT7ez7Z0m3+nIaViareifSm//IG/pHzAtCrULK+npNNHrvUajFKum4gYSMksiSq5RRmvQIs+vzg0DvsZXAP19w02/uNV8G5SefTXk5q5Z+JM5dYaWM7sP0TNDkWHssD9j0xZlnhZTWsBM/7Vmw3R0nvZR",
         *         "associated_data": "transaction",
         *         "nonce": "HipFwys1ToyA"
         *     }
         * }
         */
        // 读取json树
        JsonNode jsonNode = null;
        try {
            jsonNode = objectMapper.readTree(notify);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }

        /**
         *
         *  {
         *     "mchid": "",
         *     "appid": "",
         *     "out_trade_no": "751b1db31b6240748aefc580cd674307",
         *     "transaction_id": "4200001121202109282704065018",
         *     "trade_type": "JSAPI",
         *     "trade_state": "SUCCESS",
         *     "trade_state_desc": "支付成功",
         *     "bank_type": "OTHERS",
         *     "attach": "",
         *     "success_time": "2021-09-28T13:50:48+08:00",
         *     "payer": {
         *         "openid": ""
         *     },
         *     "amount": {
         *         "total": 1,
         *         "payer_total": 1,
         *         "currency": "CNY",
         *         "payer_currency": "CNY"
         *     }
         * }
         *
         */

        String eventType = jsonNode.get("event_type").asText();
        // 支付成功
        if (eventType.equals("TRANSACTION.SUCCESS")) {
            JsonNode childField = jsonNode.get("resource");
            String nonce = childField.get("nonce").asText();
            String associatedData = childField.get("associated_data").asText();
            String ciphertext = childField.get("ciphertext").asText();
            String resourceJson = WxPayUtil.decryptNotifyV3(associatedData, nonce, ciphertext, "ApiKey");

            JsonNode tradeDetail = null;
            try {
                tradeDetail = objectMapper.readTree(resourceJson);
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
            log.info("resource \n {}", tradeDetail.toString());

            // 外部订单号码
            String outTradeNo = tradeDetail.get("out_trade_no").asText();
        }
        return "";
    }
}
